package com.hj.monitor.domain.service;

import com.alibaba.fastjson.JSONObject;
import com.hj.monitor.domain.model.entity.MonitorDataMapEntity;
import com.hj.monitor.domain.model.entity.MonitorFlowDesignerEntity;
import com.hj.monitor.domain.model.valobj.MonitorTreeConfigVO;
import com.hj.monitor.infrastructure.po.MonitorDataMap;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
import org.springframework.stereotype.Service;
import com.hj.monitor.domain.model.entity.MonitorDataEntity;
import com.hj.monitor.domain.model.valobj.GatherNodeExpressionVO;
import com.hj.monitor.domain.repository.IMonitorRepository;
import com.hj.monitor.types.Constants;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 日志分析服务
 *
 * @author 黄健
 * @date 2024/12/05
 */
@Service
public class LogAnalyticalService implements ILogAnalyticalService {

    @Resource
    private IMonitorRepository repository;

    /**
     * 执行日志数据解析并保存监控数据
     *
     * 本方法根据提供的系统名、类名、方法名查询相应的解析规则，然后根据这些规则解析日志列表中的信息，
     * 提取所需的监控数据属性，并将其保存到监控数据实体中
     *
     * @param systemName 系统名称，用于查询解析规则
     * @param className 类名称，与系统名一起用于精确查询解析规则
     * @param methodName 方法名称，进一步精确查询解析规则
     * @param logList 日志列表，包含需要解析的日志信息
     * @throws OgnlException 当使用OGNL表达式解析日志时发生错误
     */
    @Override
    public void doAnalytical(String systemName, String className, String methodName, List<String> logList) throws OgnlException {
        // 查询匹配解析节点
        List<GatherNodeExpressionVO> gatherNodeExpressionVOs = repository.queryGatherNodeExpressionVO(systemName, className, methodName);
        if (null == gatherNodeExpressionVOs || gatherNodeExpressionVOs.isEmpty()) {
            // 如果没有找到匹配的解析规则，则不执行任何操作
            return;
        }

        for (GatherNodeExpressionVO gatherNodeExpressionVO : gatherNodeExpressionVOs) {
            // 根据监控ID查询监控名称
            String monitoryName = repository.queryMonitoryNameByMonitoryId(gatherNodeExpressionVO.getMonitorId());

            // 遍历当前解析节点的所有字段
            List<GatherNodeExpressionVO.Filed> fileds = gatherNodeExpressionVO.getFileds();
            for (GatherNodeExpressionVO.Filed filed : fileds) {
                // 获取当前字段对应的日志索引
                Integer logIndex = filed.getLogIndex();

                // 获取日志名称，并与字段的日志名称进行匹配
                String logName = logList.get(0);
                if (!logName.equals(filed.getLogName())) {
                    // 如果日志名称不匹配，则跳过当前字段的处理
                    continue;
                }

                // 初始化属性值字符串
                String attributeValue = "";
                // 根据日志索引获取日志内容
                String logStr = logList.get(logIndex);
                if ("Object".equals(filed.getLogType())) {
                    // 如果日志类型为Object，则使用OGNL表达式解析日志内容
                    OgnlContext context = new OgnlContext();
                    context.setRoot(JSONObject.parseObject(logStr));
                    Object root = context.getRoot();
                    attributeValue = String.valueOf(Ognl.getValue(filed.getAttributeOgnl(), context, root));
                } else {
                    // 对于非Object类型的日志，直接提取属性值
                    attributeValue = logStr.trim();
                    if (attributeValue.contains(Constants.COLON)) {
                        // 如果属性值包含冒号，则取冒号后的部分作为属性值
                        attributeValue = attributeValue.split(Constants.COLON)[1].trim();
                    }
                }

                // 构建监控数据实体并设置相关属性
                MonitorDataEntity monitorDataEntity = MonitorDataEntity.builder()
                        .monitorId(gatherNodeExpressionVO.getMonitorId())
                        .monitorName(monitoryName)
                        .monitorNodeId(gatherNodeExpressionVO.getMonitorNodeId())
                        .systemName(gatherNodeExpressionVO.getGatherSystemName())
                        .clazzName(gatherNodeExpressionVO.getGatherClazzName())
                        .methodName(gatherNodeExpressionVO.getGatherMethodName())
                        .attributeName(filed.getAttributeName())
                        .attributeField(filed.getAttributeField())
                        .attributeValue(attributeValue)
                        .build();

                // 保存监控数据实体到数据库
                repository.saveMonitoryData(monitorDataEntity);
            }

        }

    }

    @Override
    public List<MonitorDataMapEntity> queryMonitorDataMapEntityList() {
        return repository.queryMonitorDataMapEntityList();
    }

    @Override
    public MonitorTreeConfigVO queryMonitorFlowData(String monitorId) {
        return repository.queryMonitorFlowData(monitorId);
    }

    @Override
    public List<MonitorDataEntity> queryMonitorDataEntityList(MonitorDataEntity monitorDataEntity) {
        return repository.queryMonitorDataEntityList(monitorDataEntity);
    }

    @Override
    public void updateMonitorFlowDesigner(MonitorFlowDesignerEntity monitorFlowDesignerEntity) {
        repository.updateMonitorFlowDesigner(monitorFlowDesignerEntity);
    }


}
